/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dameki.core;

import dameki.game.FakeStone;
import dameki.game.GameMove;
import dameki.game.Stone;
import dameki.game.player.Player;
import dameki.ki.ValuedGameMove;
import java.util.ArrayList;

/**
 *
 * @author Tobi
 */
public class CheckPlayer {

    public static ArrayList<GameMove> getPossibleJumps(Player player, Stone[][] field) {
        ArrayList<GameMove> possible_jumps = new ArrayList<>();
        for (FakeStone s : getPlayerStones(field, player.getColor())) {
            ArrayList<GameMove> moves = getPossibleMoves(s, field, player.col);
            if (moves != null) {
                for (GameMove m : moves) {
                    if (Math.abs(m.getPosX() - s.fakeX) > 1) {
                        possible_jumps.add(m);
                    }
                }
            }
        }
        if (possible_jumps.isEmpty()) {
            return null;
        } else {
            return possible_jumps;
        }
    }

    private static ArrayList<GameMove> getPossibleMoves(FakeStone s, Stone[][] field, int col) {
        int posX, posY;
        posX = s.fakeX;
        posY = s.fakeY;

        ArrayList<GameMove> result = new ArrayList<>();
        //if no Dame
        try {
            //top right empty//bottom left
            if (field[posY + col][posX + 1] == null) {
                GameMove potenialMove = new GameMove(new Stone(s), posY + col, posX + 1);
                result.add(potenialMove);
            }//enemy at top right
            else if (field[posY + col][posX + 1].getColor() != s.getColor()) {
                //no stone at 2top 2right
                if (field[posY + 2 * col][posX + 2] == null) {
                    GameMove potenialMove = new GameMove(new Stone(s), posY + 2 * col, posX + 2);
                    result.add(potenialMove);
                }
            }
        } catch (IndexOutOfBoundsException ex) {
        }
        try {
            //top left empty
            if (field[posY + col][posX - 1] == null) {
                GameMove potenialMove = new GameMove(new Stone(s), posY + col, posX - 1);
                result.add(potenialMove);
            } //enemy at top left // top right
            else if (field[posY + col][posX - 1].getColor() != s.getColor()) {
                //no stone at 2top 2left
                if (field[posY + 2 * col][posX - 2] == null) {
                    GameMove potenialMove = new GameMove(new Stone(s), posY + 2 * col, posX - 2);
                    result.add(potenialMove);
                }
            }
        } catch (IndexOutOfBoundsException ex) {
        }
        //if Dame
        if (s.IsDame()) {
            try {
                //top right empty
                if (field[posY - col][posX + 1] == null) {
                    GameMove potenialMove = new GameMove(new Stone(s), posY - col, posX + 1);
                    result.add(potenialMove);
                }//enemy at top right
                else if (field[posY - col][posX + 1].getColor() != s.getColor()) {
                    //no stone at 2top 2right
                    if (field[posY - 2 * col][posX + 2] == null) {
                        GameMove potenialMove = new GameMove(new Stone(s), posY - 2 * col, posX + 2);
                        result.add(potenialMove);
                    }
                }
            } catch (IndexOutOfBoundsException ex) {
            }
            try {
                //top left empty
                if (field[posY - col][posX - 1] == null) {
                    GameMove potenialMove = new GameMove(new Stone(s), posY - col, posX - 1);
                    result.add(potenialMove);
                } //enemy at top left // top right
                else if (field[posY - col][posX - 1].getColor() != s.getColor()) {
                    //no stone at 2top 2left
                    if (field[posY - 2 * col][posX - 2] == null) {
                        GameMove potenialMove = new GameMove(new Stone(s), posY - 2 * col, posX - 2);
                        result.add(potenialMove);
                    }
                }
            } catch (IndexOutOfBoundsException ex) {
            }
        }
        return result;
    }
    
    public static Stone[][] UndoMove(GameMove move,Stone[][] field){
        Stone[][] tempfield = new Stone[8][8];
        for(int z=0;z<field.length;z++){
            System.arraycopy(field[z], 0, tempfield[z], 0, field[z].length);
        }
        if(move!=null){
            int Ydist = move.getStone().getPosY()-move.getPosY();
            int Xdist = move.getStone().getPosX()-move.getPosX();

            if(Xdist==2 || Xdist==-2){
                tempfield[move.getStone().getPosY()-Ydist/2][move.getStone().getPosX()-Xdist/2]=null;
            }
            tempfield[move.getStone().getPosY()][move.getStone().getPosX()]=null;
            tempfield[move.getPosY()][move.getPosX()]=move.getStone();
        }
        return tempfield;
    }   
    
    public static Stone[][] getNewFieldState(GameMove move,Stone[][] field){
        
        Stone[][] tempfield = new Stone[8][8];
        for(int z=0;z<field.length;z++){
            System.arraycopy(field[z], 0, tempfield[z], 0, field[z].length);
        }
        if(move!=null){
            int pos[] = getTempPosOfStone(move.getStone(), field);
            int Ydist = pos[0]-move.getPosY();
            int Xdist = pos[1]-move.getPosX();

            if(Xdist==2 || Xdist==-2){
                tempfield[pos[0]-Ydist/2][pos[1]-Xdist/2]=null;
            }
            tempfield[pos[0]][pos[1]]=null;
            tempfield[move.getPosY()][move.getPosX()]=move.getStone();
        }
        return tempfield;
    }   
    
    private static ArrayList<FakeStone> getPlayerStones(Stone[][] field,boolean color){
        ArrayList list =  new ArrayList();
        for(int y=0;y<field.length;y++){
            for(int x=0;x<field[y].length;x++){
                if(field[y][x]!=null && field[y][x].getColor()==color){
                    list.add(new FakeStone(field[y][x],x,y));
                }
            }
        }
        return list;
    }
    
    public static boolean checkMove(GameMove move, int[] pos, boolean color,Stone[][] field) {
        int col = color?1:-1;
        int posX,posY;
        if(pos==null){
            posX=move.getStone().getPosX();
            posY=move.getStone().getPosY();
        }else{
            posX=pos[1];//pos[1] --> x
            posY=pos[0];//pos[0] --> y
        }
        
        if (move.getPosY() >= 0 && move.getPosY() < 8 && move.getPosX() >= 0 && move.getPosX() < 8) {
            //if targetField is empty
            if (field[move.getPosY()][move.getPosX()] == null) {
                //no jump
                if (move.getPosY() == posY + col) {
                    if (move.getPosX() == posX + 1 || move.getPosX() == posX + -1) {
                        return true;
                    }
                } //jump
                else if (move.getPosY() == posY + 2 * col) {
                    //jump to the right
                    if (move.getPosX() == posX + 2) {
                        Stone dead = field[move.getPosY() - col][move.getPosX() - 1];
                        if (dead.getColor() != color) {
                            return true;
                        }
                        //jump to the left
                    } else if (move.getPosX() == posX - 2) {
                        Stone dead = field[move.getPosY() - col][move.getPosX() + 1];
                        if (dead.getColor() != color) {
                            return true;
                        }
                    }
                }
                if (move.getStone().IsDame()) {
                    //no jump
                    if (move.getPosY() == posY - col) {
                        if (move.getPosX() == posX + 1 || move.getPosX() == posX + -1) {
                            return true;
                        }
                    } //jump
                    else if (move.getPosY() == posY - 2 * col) {
                        //jump to the right
                        if (move.getPosX() == posX + 2) {
                            Stone dead = field[move.getPosY() + col][move.getPosX() - 1];
                            if (dead.getColor() != color) {
                                return true;
                            }
                            //jump to the left
                        } else if (move.getPosX() == posX - 2) {
                            Stone dead = field[move.getPosY() + col][move.getPosX() + 1];
                            if (dead.getColor() != color) {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        } else {
            return false;
        }
    }
    
    private static int[] getTempPosOfStone(Stone s,Stone[][] field){
        for(int y=0;y<field.length;y++){
            for(int x=0;x<field.length;x++){
                if(field[y][x]!=null && field[y][x]==s){
                    return new int[]{y,x};
                }
            }
        }
        return null;
    }
}
